﻿using System;
using System.Web;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;

using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.property;
using umbraco.BusinessLogic.Actions;
using umbraco.interfaces;
using umbraco.cms.businesslogic.web;
using FergusonMoriyama.Umbraco;

namespace FergusonMoriyama.Umbraco.FMLinkCheck
{
    class FMLinkCheckAction : IActionHandler
    {
        string IActionHandler.HandlerName()
        {
            return "FergusonMoriyama.Umbraco.FMLinkCheck.FMLinkCheckAction";
        }

        IAction[] IActionHandler.ReturnActions()
        {
            return new IAction[] { new ActionPublish() };
        
        }

        Boolean IActionHandler.Execute(Document doc, IAction action)
        {
           


            Log.Add(LogTypes.Debug, -1, "Link checker action fired.");
            
            int docId = doc.Id;
            String docUrl = umbraco.library.NiceUrl(docId);

            Log.Add(LogTypes.Debug, -1, "Published " + docUrl);
            if (docUrl.IndexOf("/") == 0) { docUrl = docUrl.Substring(1); }
            Uri u = HttpContext.Current.Request.Url;

            String baseUrl = u.Scheme + "://" + u.Host + ":" + u.Port + "/";
            String publishedPageUrl = baseUrl + docUrl;

            int brokenLinkCount = 0;
            String brokenLinkMessage = "";

            Log.Add(LogTypes.Debug, -1, "Requesting " + publishedPageUrl);

            PageRequester p = new PageRequester();

            if (p.getPage(publishedPageUrl))
            {
                String pageData = p.Content;

                MatchCollection links = Regex.Matches(pageData, @"href\=""(.*?)""");
                foreach (Match link in links)
                {
                    String linkValue = link.Groups[1].Value;
                    if (linkValue.IndexOf("://") == -1)
                    {
                        if (linkValue.IndexOf("/") == 0)
                        {

                            linkValue = linkValue.Substring(1);
                            linkValue = baseUrl + linkValue;
                        }
                        else 
                        {
                            String root = publishedPageUrl;
                            if (root.IndexOf("/") == 0) { root = root.Substring(1);  }
                            linkValue = root.Substring(0, root.LastIndexOf("/") + 1) + linkValue;
                            
                        }
                    }
                    
                    Log.Add(LogTypes.Debug, -1, "Found link " + linkValue);

                    PageRequester q = new PageRequester();
                    if(!q.getPage(linkValue))
                    {
                        brokenLinkCount++;
                        brokenLinkMessage += linkValue + ": " + q.Error + "\n";
                    }
                }

                if (brokenLinkCount > 0)
                {
                    Log.Add(LogTypes.Error, -1, brokenLinkMessage);

                    String from = umbraco.UmbracoSettings.NotificationEmailSender;
                    String subject = "Found " + brokenLinkCount + " broken links in " + publishedPageUrl;
                    Log.Add(LogTypes.Debug, -1, subject);
                    String to = doc.User.Email;

                    Log.Add(LogTypes.Debug, -1, to);
                    foreach (DocumentVersionList dl in doc.GetVersions())
                    {
                            to = dl.User.Email; 
                    }

                    Log.Add(LogTypes.Debug, -1, "after: " + to);

                    umbraco.library.SendMail(from, to, subject, brokenLinkMessage, false);

                }

            }
            else { Log.Add(LogTypes.Error, -1, p.Error);  } 

            return true;
        }
    }
}
